package com.demo.modules.sys.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.demo.common.constant.Constant;
import com.demo.common.utils.PageUtils;
import com.demo.common.base.QueryBase;
import com.demo.config.cache.ObjectCacheConfig;
import com.demo.modules.sys.dao.SysMenuDao;
import com.demo.modules.sys.entity.SysMenuEntity;
import com.demo.modules.sys.form.SysMenuQueryForm;
import com.demo.modules.sys.service.SysMenuService;
import com.demo.modules.sys.service.SysRoleMenuService;
import com.demo.modules.sys.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service("sysMenuService")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuDao, SysMenuEntity> implements SysMenuService {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    /**
     * 分页条件查询
     *
     * @param params
     * @return
     */
    @Override
    public PageUtils<SysMenuEntity> queryPage(SysMenuQueryForm params) {
        IPage<SysMenuEntity> page = this.page(
                new QueryBase<SysMenuEntity>().getPage(params),
                new QueryBase<SysMenuEntity>().getQuery(SysMenuQueryForm.getQueryWrapper(params), params)
        );
        return new PageUtils<SysMenuEntity>(page);
    }

    @Override
    public List<SysMenuEntity> queryListParentId(Long parentId) {
        return this.list(new LambdaQueryWrapper<SysMenuEntity>()
                .eq(SysMenuEntity::getParentId, parentId)
                .orderByAsc(SysMenuEntity::getOrderNum)
        );
    }

    @Override
    public List<SysMenuEntity> getUserMenuList(Long userId) {
        //系统管理员，拥有最高权限
        if (userId == Constant.SUPER_ADMIN) {
            List<SysMenuEntity> sysMenuEntities = this.list(new LambdaQueryWrapper<SysMenuEntity>()
                    .ne(SysMenuEntity::getType, Constant.MenuType.BUTTON.getValue())
                    .eq(SysMenuEntity::getIsShow, 1)
                    .orderByAsc(SysMenuEntity::getOrderNum)
            );
            return getChild((long) 0, sysMenuEntities);
        }

        //用户菜单列表
        return getChild((long) 0, sysUserService.queryAllMenu(userId));
    }

    /**
     * 递归查找子菜单
     *
     * @param id       当前菜单id
     * @param rootMenu 要查找的列表
     * @return
     */
    private List<SysMenuEntity> getChild(Long id, List<SysMenuEntity> rootMenu) {
        // 子菜单
        List<SysMenuEntity> childList = new ArrayList<SysMenuEntity>();
        rootMenu.forEach(sysMenuEntity -> {
            // 遍历所有节点，将父菜单id与传过来的id比较
            if (sysMenuEntity.getParentId().equals(id)) {
                childList.add(sysMenuEntity);
            }
        });
        // 递归退出条件
        if (childList.size() == 0) {
            return null;
        } else {
            // 把子菜单的子菜单再循环一遍
            childList.forEach(sysMenu -> {
                // 递归
                sysMenu.setChildList(getChild(sysMenu.getId(), rootMenu));
            });
        }
        return childList;
    }

    @Override
    public boolean save(SysMenuEntity entity) {
        super.save(entity);

        //更新缓存
        ObjectCacheConfig.menuCache.put(entity.getId(), entity);

        return true;
    }

    @Override
    public boolean updateById(SysMenuEntity entity) {
        super.updateById(entity);

        //更新缓存
        ObjectCacheConfig.menuCache.put(entity.getId(), entity);

        return true;
    }

    @Override
    public void delete(Long menuId) {
        //删除菜单
        this.removeById(menuId);
        //删除菜单与角色关联
        //sysRoleMenuService.removeByMap(new MapUtils().put("menu_id", menuId));
        //更新缓存
        ObjectCacheConfig.menuCache.get(menuId).setIsDel(Constant.INT_Y);
    }

    @Override
    public List<SysMenuEntity> queryAllChildren(Long parentId) {
        List<SysMenuEntity> allList = new ArrayList<>();
        ObjectCacheConfig.menuCache.forEach(menu -> {
            if (menu.getIsDel() == Constant.INT_N) {
                allList.add(menu);
            }
        });
        return getAllChildrenList(allList, parentId);
    }

    /**
     * 递归查询所有子节点
     *
     * @param allList  菜单集合
     * @param parentId 父级id
     * @return 子菜单集合
     */
    private List<SysMenuEntity> getAllChildrenList(List<SysMenuEntity> allList, Long parentId) {
        List<SysMenuEntity> childrenList = new ArrayList<>();
        // 判空
        if (allList == null || allList.size() == 0) {
            return childrenList;
        }
        // 找出所有的下一级节点
        for (SysMenuEntity menu : allList) {
            if (parentId.equals(menu.getParentId())) {
                childrenList.add(menu);
            }
        }
        // 当前所有子级集合
        List<SysMenuEntity> allChildrenList = new ArrayList<>(childrenList);
        // 遍历下一级节点
        if (childrenList.size() > 0) {
            for (SysMenuEntity menu : childrenList) {
                // 递归
                List<SysMenuEntity> children = getAllChildrenList(allList, menu.getId());
                if (children.size() > 0) {
                    allChildrenList.addAll(children);
                }
            }
        }
        return allChildrenList;
    }
}
